using System;
using System.Collections.Generic;
using System.Text;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;

namespace ITCrossing
{
	/// <summary>
	/// IPublishable contains the core set of properties and methods required to support a publishing 
	/// API.  Additional publishing API features will be made available in optional interfaces that
	/// can be implemented to note the support for features such as headers and footers (IWrappable)
	/// as well as other features such as support for Pingbacks or Trackbacks (ILinkable)
	/// </summary>
	public interface IPublishable
	{
		# region Public Properties 
		/// <summary>
		/// ProviderKey should be set to the Friendly Name of the module for
		/// which this provider is being implemented.
		/// </summary>
		string ProviderKey { get;}

		/// <summary>
		/// ManifestFilePath is the path including the filename to the manifest file used to determine 
		/// the settings available in Windows Live Writer.  An example path might
		/// be /DesktopModules/itcMetaPost/manifests/wlwblog.xml.  See the following URL for 
		/// information regarding what Content can be placed in a WLW manifest file:
		/// http://msdn2.microsoft.com/en-us/library/bb463260.aspx
		/// </summary>
		string ManifestFilePath { get;}
		
		/// <summary>
		/// LocalizationFilePath is the path including the filename to the 
		/// resource file used by the module to retrieve the error messages
		/// shown to the user (eg. "/DesktopModules/custommodule/App_LocalResources/customfilename")
		/// Note that the filename should not include the file extension.
		/// </summary>
		string LocalizationFilePath { get;}

		/// <summary>
		/// ImageUploadPath determines the path where metaPost will
		/// upload the images that are included in new or edited entries.
		/// </summary>
		string ImageUploadPath { get;}

		/// <summary>
		/// AttachmentUploadPath is used to specify the location of attachments added
		/// to a post or page.
		/// </summary>
		string AttachmentUploadPath { get;}

		/// <summary>
		/// SettingsUserControlPath is for future use.  It will return the path to the
		/// the settings user control for this provider.  
		/// </summary>
		string SettingsUserControlPath { get;}
		# endregion

		# region GetMethods
		/// <summary>
		/// The purpose of this procedure is to provide a list of all the modules in a 
		/// given portal to which the currently logged on user has either insert, update
		/// or delete access.  Note, this may not always correspond to an actual module.
		/// For example, with the DNN Blog module provider, a list of blogs is returned
		/// along with URL of where each blog is available within the site.
		/// </summary>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		/// <param name="providerKey"></param>
		ModuleInfoStruct[] GetModulesForUser(UserInfo userInfo,
											 PortalSettings portalSettings,
											 string providerKey);


		/// <summary>
		/// GetRecentItems returns a list of the recent items added to the module.  For example, with
		/// the blog module, the list would return all the recent blog entries.  For the Text/HTML provider, 
		/// this method would return a list of the recently added Text/HTML modules in the site.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="numberOfItems"></param>
		/// <param name="requestType">GetRecentItems can be called for a number of reasons.  In Windows Live Writer,
		/// users are able to retrieve a list of recent posts or recent pages.  The requestType parameter is used
		/// to denote whether a list of pages or posts is being requested.  Additionally, WLW may request a list 
		/// of hiearchical pages to show pages when allowing a parent page to be assigned to a new page.  The values for this enum
		/// are RecentPosts, RecentPages and RecentPagesHiearchical.</param>
		/// <param name="providerKey"></param>
		/// <returns></returns>
		Item[] GetRecentItems(string 
						moduleLevelId, 
						UserInfo userInfo, 
						PortalSettings portalSettings, 
						int numberOfItems, 
						RecentItemsRequestType requestType, 
						string providerKey);
		
		/// <summary>
		/// GetItem is used to retrieve a specific item, which may be a page or a post if your module supports
		/// both concepts.  In cases where a module supports both pages and posts, a concept made available in 
		/// Windows Live Writer, but not in Word 2007 or in many other publishing clients, the itemType parameter 
		/// can be used to distinguish between when this method is being called to add a page or a post.  If your 
		/// provider doesn't support a distinction between pages and posts, then simply ignore the itemType parameter.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="itemId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="itemType"></param>
		/// <returns></returns>
		Item GetItem(string itemId,
						UserInfo userInfo,
						PortalSettings portalSettings,
						ItemType itemType);
		# endregion

		# region Add, Edit and Delete Methods

		/// <summary>
		/// NewItem is used for creating new items (either pages or posts).  The implementation 
		/// in your provider can distinguish between page and post requests for NewItem by the 
		/// ItemType property of the Item struct.  Additional properties of the Item Struct which 
		/// may be of interest in the implmentation of this method are: Publish, StyleDetectionPost,StyleId, and ItemType.
		/// See the comments associated with each of these properties of the Item struct for more information.
		/// </summary>
		/// <param name="moduleLevelId">String - ModuleId is a very loose concept here.  Anything can be tracked in this variable as long as it is consistent.  For the Blog module, the BlogId is passed and for the Text/HTML module, the ModuleId is passed and for the Ventrian News Articles module, the ArticleId is passed.  This value is based on the value sent to Windows Live Writer when GetModulesForUser is called. </param>
		/// <param name="userInfo">DotNetNuke UserInfo object.  This UserInfo object is retrieved by metaPost and made available to every method call in the MetaPostProvider interface.</param>
		/// <param name="portalSettings">DotNetNuke PortaSettings object - This is provided to make it easier to work with metaPost.  metaPost does all the work behind the scenes of identifying the right portalSettings object based on the requested URL.</param>
		/// <param name="item">Custom Struct - The item struct contains a list of fields sent through the MetaWeblog API.  The properties have been renamed to make sense in more general applications outside of just blogs.</param>
		/// <returns></returns>
		string NewItem(string moduleLevelId,
						UserInfo userInfo,
						PortalSettings portalSettings,
						Item item);

		/// <summary>
		/// EditItem is called to edit either a page or a post.  The difference
		/// between the two is denoted in a property of the Item struct (ItemType).
		/// An additional property of the Item struct that may be important to the 
		/// implementation of the EditItem method is the Publish property.  This is 
		/// set to true when the item should be published.  The default setting of 
		/// false denotes that the item may be saved as a draft.
		/// 
		/// It's important to note that when Windows Live Writer sends the information 
		///		for a post edit, the moduleLevelId is not passed.  For implementation of 
		///		this procedure in providers which do not support pages, the moduleLevelId 
		///		should be ignored and attempts to get the moduleId can be made by calling
		///		GetModuleIdFromItemId or a similar private procedure.
		/// 
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="item"></param>
		/// <returns></returns>
		bool EditItem(	string			moduleLevelId, 
						UserInfo		userInfo, 
						PortalSettings	portalSettings, 
						Item			item);

		/// <summary>
		/// DeleteItem is used to delete either a page or a post.  The difference between the two is noted 
		/// in the itemType parameter which is an enumeration set to either Page or Post.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="itemId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="itemType"></param>
		/// <returns></returns>
		bool DeleteItem(string itemId,
						UserInfo userInfo,
						PortalSettings portalSettings,
						ItemType itemType);

		# endregion

		# region Category Related Methods

		/// <summary>
		/// GetCategories retrieves a list of categories for a particular module.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		ItemCategoryInfo[] GetCategories(string moduleLevelId,
		                                 UserInfo userInfo,
		                                 PortalSettings portalSettings);

		/// <summary>
		/// SetItemCategories is needed for supporting the ability to pass categories separately. 
		/// With the next release of WLW (This is being written 07/02/08), all posts will 
		/// pass the category through the SetCategory method.  However, the categories will
		/// also still be passed inline if this option is enabled in the manifest file.
		/// </summary>
		/// <param name="itemId"></param>
		/// <param name="itemCategories"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		bool SetItemCategories(string itemId, ItemCategory[] itemCategories, UserInfo userInfo, PortalSettings portalSettings);

		/// <summary>
		/// GetItemCategories was added along with SetCategory (see note above) so support changes in 
		/// Windows Live Writer.  GetItemCategories returns an array of ItemCategory structs related to an item.
		/// </summary>
		/// <param name="itemId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		ItemCategory[] GetItemCategories(string itemId, UserInfo userInfo, PortalSettings portalSettings);


		/// <summary>
		/// Used to add a new category for modules which support this feature.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="category"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		int NewCategory(string moduleLevelId, NewItemCategory category, UserInfo userInfo, PortalSettings portalSettings);
		# endregion

	}

	/// <summary>
	/// ILinkable contains the core methods needed for enabling Trackback and Pingback
	/// and for making use of core services that may be provided in the publishing adapter
	/// used to integrate with your publishing interfaces.  Some modules handle
	/// their own trackback capability.  If this is the case, you may choose not to implement
	/// this optional interface.
	/// </summary>
	public interface ILinkable
	{
		string GetModuleName(string moduleLevelId, UserInfo userInfo, PortalSettings portalSettings);

		string GetPermaLink(string moduleLevelId, string itemId, UserInfo userInfo, PortalSettings portalSettings);

		TrackbackAndPingSettings GetPingbackSettings(string moduleLevelId, UserInfo userInfo, PortalSettings portalSettings);

	}
	
	/// <summary>
	/// IWrappable contains methods needed by publishing adapters which are written to use 
	/// IPublishable and which allow for Header and Footer content to be written into each
	/// post.  The current version of the blog module does not support headers and footers.
	/// </summary>
	public interface IWrappable
	{
		/// <summary>
		/// HeaderContent is not used by the blog module.  
		/// </summary>
		string HeaderContent
		{
			get;
		}
		/// <summary>
		/// FooterContent is not used by the blog module.  
		/// </summary>
		string FooterContent
		{
			get;
		}
	}

}